"""
conanfile.py for demo;
以下指令用于屏蔽无用警告信息
"""
# pyright: reportGeneralTypeIssues=false
# pyright: reportUnknownMemberType=false
# pyright: reportUnknownVariableType=false
# pyright: reportMissingModuleSource=false
# pyright: reportAttributeAccessIssue=false
# pyright: reportMissingImports=false
# pyright: reportOptionalCall=false
# pyright: reportOptionalMemberAccess=false

import os
import re
import sys

from conan import ConanFile
from conan.tools import files as cnn_files
from conan.tools.build import check_min_cppstd
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout


class DemoConan(ConanFile):
    name = "demo"
    version = "0.1"
    settings = "os", "compiler", "build_type", "arch"  # from settings.yml
    generators = "CMakeDeps"  # 用于生成 cmake 依赖文件,  用于 cmake find_package
    license = "MIT"
    author = "HuiTaiLang"

    # 指定需要的第三方库
    requires = ["fmt/11.2.0", "eigen/3.4.0", "spdlog/1.15.3"]

    # 让 Conan 2 自动检测并导出 CMakeLists.txt;
    # 主要为了分享本项目源代码给他人使用
    exports_sources = "CMakeLists.txt", "src/*"

    def layout(self):
        # 推荐 layout：把 build 文件夹放在项目根
        cmake_layout(self)

    def validate(self):
        check_min_cppstd(self, "14")

    # 可以添加 工具依赖(而非库依赖), 例如 cmake,ninja,binutils 等等
    def build_requirements(self):
        if self.settings.os == "Windows":
            # Windows 平台可以添加特定的构建工具
            return

        if self.settings.os == "Linux":
            if self.settings.compiler != "gcc":
                print(sys.stderr, "Linux 平台目前仅支持 gcc 编译器")
                return
            if float(str(self.settings.compiler.version)) < 9:  # centos8
                print(f"[ymy] gcc version: {self.settings.compiler.version}")
                self.tool_requires("cmake/4.1.0")
                self.tool_requires("ninja/1.13.1")
            else:  # 其他 linux 版本
                self.tool_requires("cmake/4.1.0")
                self.tool_requires("ninja/1.13.1")

    def generate(self):
        ##--- 设定编译的线程数为8
        # self.conf_info.define("tools.build:jobs", 8)
        # 自定义 cmake generators; 和 CMake --help 输出中的 候选列表 相同
        if self.settings.os == "Windows":
            tc = CMakeToolchain(self, generator="Visual Studio 17 2022")
        elif self.settings.os == "Linux":
            tc = CMakeToolchain(self, generator="Ninja")
        tc.generate()

        # 把依赖包里的 .so 全部拷到 build/ 目录
        if True:
            for dep in self.dependencies.values():
                if dep.cpp_info.bindirs:
                    self.output.info(f"[ymy]{dep.cpp_info.bindirs}")
                    cnn_files.copy(self, "*.so*", dep.cpp_info.bindirs[0], dst=f"{self.build_folder}/runtime", keep_path=False)
                for libdir in dep.cpp_info.libdirs:
                    self.output.info(f"[ymy]{dep.cpp_info.libdirs}")
                    cnn_files.copy(self, "*.so*", libdir, dst=f"{self.build_folder}/runtime", keep_path=False)
                    cnn_files.copy(self, "*.dylib", dep.cpp_info.libdirs[0], self.deploy_folder, keep_path=False)

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    ## 关键：自定义 deployer 函数，名字固定; 命令行调用
    ## conan install . --deployer-package='*' --deployer-folder=inst-demo -pr pr/gcc8_wsl_cross
    def deploy(self):
        # 1. 收集所有 Conan 依赖的 bindirs / libdirs
        for dep in self.dependencies.values():
            # 2. 只拷动态库，跳过静态库、CMake 文件等
            # 可以添加更多的过滤逻辑
            if dep.cpp_info.bindirs:
                cnn_files.copy(self, "*.dll", dep.cpp_info.bindirs[0], self.deploy_folder, keep_path=False)
            if dep.cpp_info.libdirs:
                cnn_files.copy(self, "*.so*", dep.cpp_info.libdirs[0], self.deploy_folder, keep_path=False)
                cnn_files.copy(self, "*.dylib", dep.cpp_info.libdirs[0], self.deploy_folder, keep_path=False)

        # 3. 显式剔除系统白名单（可选）
        # -------- 2. 系统库白名单正则 --------
        sys_lib_re = re.compile(
            r"(?:^|/)("
            r"ld-linux-.*\.so.*|"  # 动态加载器
            r"libc\.so.*|"
            r"libm\.so.*|"
            r"libdl\.so.*|"
            r"libpthread\.so.*|"
            r"librt\.so.*|"
            r"libresolv\.so.*|"
            r"libgcc_s\.so.*|"
            r"libstdc\+\+\.so.*|"
            r"libSystem\.dylib|"
            r"libsystem_.*\.dylib|"
            r"Kernel32\.dll|"
            r"msvcrt.*\.dll|"
            r"ucrt.*\.dll|"
            r"vcruntime.*\.dll|"
            r"api-ms-win-.*\.dll"
            r")(?:\.[0-9]+)*$",
            re.IGNORECASE,
        )

        # -------- 3. 遍历并剔除 --------
        for root, _, files in os.walk(self.deploy_folder):
            for f in files:
                if sys_lib_re.match(f):
                    os.unlink(os.path.join(root, f))
